/**
 * 
 */
package org.cmcc.pcap.jpcap.capture;

import java.io.File;
import java.io.FilenameFilter;
import java.math.RoundingMode;
import java.text.DecimalFormat;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;

import com.cmcc.xdr.util.ProtocolSpringContextUtils;

/**
 * @Date 2018年6月14日 下午6:37:11
 * @author Amish
 */
public class PacketAnalysis {
	private static Logger logger = LogManager.getLogger(PacketAnalysis.class);
//	private JdbcTemplate jdbcTemplate;
//	//private static int pcapDealThreads = 1;
//	
//	static {
//		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/applicationContext.xml"); //
//		jdbcTemplate = (JdbcTemplate)ctx.getBean("jdbcTemplate");
//		//pcapDealThreads = PacketAnalysisConfig.getConfigAsInt("pcap.deal.threads") > 0 ? PacketAnalysisConfig.getConfigAsInt("pcap.deal.threads") : 1;
//		
//		
//	}

	static FilenameFilter filenameFilter = new FilenameFilter() {
		@Override
		public boolean accept(File file, String name) {// 这里的name属性，表示文件或文件夹的名字，
														// 可以直接根据名字做前缀、后缀以及正则表达式等进行过滤，
														// 如：return name.startsWith("ra");
			return name.matches("(.*\\.pcap)|(.*\\.cap)");
			// return name.contains(".pcap");//性能是否不如正则表达式?
		}
	};

	public void analysis(String taskId, Class httpHandler, Class httpsHandler, Class tcpHandler, Class udpHandler,
			String pcapDir) {

		try {
			JdbcTemplate jdbcTemplate = new JdbcTemplate(ProtocolSpringContextUtils.getBean("dataSource"));
			File dir = new File(pcapDir);
			if (!dir.isDirectory()) {
				logger.error("the input is not a directory ");
				return;
			}

			File[] files = dir.listFiles(filenameFilter);

			logger.info("the fileNumber is : " + files.length);
			// logger.info("the dir total length is : "+dir.length());//8192

			long totalBytes = 0;
			for (File file : files) {
				totalBytes += file.length();
				// logger.info("the < "+file.getName()+" > file.lentgh is : "+file.length());
			}
			logger.info("the dir total length is : " + totalBytes);

			JCaptures jc = new JCaptures(taskId); // 赋值标准id,存入数据库表中
			long dealTotalBytes = 0;
			for (File file : files) {// TODO file 分组 分给多个jcpatures处理？
				logger.info("the < " + file.getName() + " > file.lentgh is : " + file.length());
				dealTotalBytes += file.length();

//				jc.complete = false;

				jc.tcp_packet_exist = false;
				jc.udp_packet_exist = false;

				jc.tcp_complete = false;
				jc.udp_complete = false;

				jc.captureFromFile(file.getAbsolutePath(), null);// fileRealSerial为true时方法内会阻塞等待所有一个文件的包处理完
				// 将处理进度写入数据库
				StringBuffer sql = new StringBuffer();
				sql.append("UPDATE STAT_TASKINFO SET  UNPACK_PROCESS_PERCENT= '");
				sql.append(proportionCalculation(dealTotalBytes, totalBytes));
				sql.append("' WHERE ID = '");
				sql.append(taskId + "'");
				try {
					jdbcTemplate.execute(sql.toString());
					logger.info("complete : " + dealTotalBytes + "/ total : " + totalBytes);
					logger.info("the pcap deal rate of progress is : "
							+ proportionCalculation(dealTotalBytes, totalBytes) + " %");
				} catch (Exception e) {
					e.printStackTrace();
					logger.error("解析数据包进度更新失败!", e);
				}
				// 群发消息，告诉所有连接到任务列表的用户任务列表进度状态有更新
//		        for(DataEyeWebSocket item: DataEyeWebSocket.getWebSocketSet()){
//		            try {
//		                item.sendMessage("unpackProgress",proportionCalculation(dealTotalBytes,totalBytes));
//		            } catch (IOException e) {
//		            	logger.error("群发消息出错：",e);
//		                e.printStackTrace();
//		                continue;
//		            }
//		        }
			}

			while (true) {
//				if(jc.complete){//当所有文件处理完时，解除阻塞
//					logger.debug("all packets deal !");
//					break;
//				}

//				if(jc.tcp_complete && jc.udp_complete){
//					logger.debug("tcp and udp packets deal !");
//					break;
//				}

				// 有tcp包，没有udp包
				logger.debug("tcp_exist:" + jc.tcp_packet_exist);
				logger.debug("udp_exist:" + jc.udp_packet_exist);
				logger.debug("tcp_complete:" + jc.tcp_complete);
				logger.debug("udp_complete:" + jc.udp_complete);

				if (jc.tcp_packet_exist && !jc.udp_packet_exist) {
					if (jc.tcp_complete) {
						logger.debug("tcp packets deal !");
						break;
					}

				}
				// 没有tcp包，有udp包
				if (!jc.tcp_packet_exist && jc.udp_packet_exist) {
					if (jc.udp_complete) {
						logger.debug("udp packets deal !");
						break;
					}

				}

				// 有tcp包，也有udp包
				if (jc.tcp_packet_exist && jc.udp_packet_exist) {
					if (jc.tcp_complete && jc.udp_complete) {
						logger.debug("tcp and udp packets deal !");
						break;
					}
				}

				Thread.sleep(1000);
			}
			jc.stop();// 显示调用stop，否则文件处理完也不会结束进程
		} catch (Exception e) {
			logger.error("some exception", e);
		}

	}

	/**
	 * 此方法目前会有 java.io.IOException: Another Jpcap instance is being used. TOFix
	 * 
	 * @param taskId
	 * @param xdrDir
	 * @param pcapDir
	 */
	@Deprecated
	public static void analysis2(String taskId, String xdrDir, String pcapDir) {
		try {

			TaskContext tc = new TaskContext(taskId, pcapDir);
			tc.analysisStart();

		} catch (Exception e) {
			logger.error("some exception", e);
		}
	}

	public static String proportionCalculation(long numerator, long denominator) {
		DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance();
		decimalFormat.setMaximumFractionDigits(2);
		decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
		float proportionNum = (float) numerator / (float) denominator * 100;

		String proportionStr = decimalFormat.format(proportionNum);
		return proportionStr;
	}

}
